package com.xyongfeng.foodManagement.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyongfeng.foodManagement.common.ErrorCode;
import com.xyongfeng.foodManagement.domain.*;
import com.xyongfeng.foodManagement.domain.dto.RoleDTO;
import com.xyongfeng.foodManagement.domain.vo.AdminInfoVO;
import com.xyongfeng.foodManagement.domain.vo.RoleVO;
import com.xyongfeng.foodManagement.exception.ThrowUtils;
import com.xyongfeng.foodManagement.mapper.RoleMapper;
import com.xyongfeng.foodManagement.service.AdminRoleService;
import com.xyongfeng.foodManagement.service.PermissionService;
import com.xyongfeng.foodManagement.service.RolePermissionService;
import com.xyongfeng.foodManagement.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xyongfeng
 * @description 针对表【role】的数据库操作Service实现
 * @createDate 2024-06-10 13:53:47
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role>
        implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private AdminRoleService adminRoleService;

    @Override
    public List<Role> getRoleByAdminId(Integer adminId) {

        return roleMapper.getRoleByAdminId(adminId);
    }

    @Override
    public Role addRole(String roleName) {

        Long count = lambdaQuery().eq(Role::getRole, roleName).count();
        ThrowUtils.throwIf(count > 0, ErrorCode.PARAMS_ERROR, "该角色已存在");

        Role role = new Role();
        role.setRole(roleName);
        save(role);

        return role;
    }

    @Override
    public List<AdminInfoVO> selectAdminByRoleId(Integer roleId) {

        List<AdminInfo> adminInfos = roleMapper.selectAdminByRoleId(roleId);

        List<AdminInfoVO> adminInfoVOS = adminInfos.stream().map(AdminInfo::convertToVO).collect(Collectors.toList());

        return adminInfoVOS;

    }


    @Override
    public List<RoleVO> selectAllRoleInfo() {

        List<RoleVO> list = list().stream().map(role -> {
            RoleVO roleVO = new RoleVO();
            roleVO.setRole(role);
            List<AdminInfoVO> adminInfoVOS = selectAdminByRoleId(role.getRoleId());

            roleVO.setAdminInfos(adminInfoVOS);

            roleVO.setPermissions(permissionService.getByRoleId(role.getRoleId()));
            return roleVO;
        }).collect(Collectors.toList());

        return list;
    }


    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean updateRole(RoleDTO roleDTO) {

        // 查找role的已有权限
        List<Integer> ownPerm = rolePermissionService.lambdaQuery()
                .eq(RolePermission::getRoleId, roleDTO.getRole().getRoleId())
                .list().stream().map(RolePermission::getPermissionId).collect(Collectors.toList());

        // 没有被选择的权限  需要添加新关系
        List<Integer> unSelectPerm = roleDTO.getPermissions()
                .stream().filter(x -> !ownPerm.contains(x)).collect(Collectors.toList());
        // 需要移除的权限
        List<Integer> removeSelPerm = ownPerm.stream()
                .filter(x -> !roleDTO.getPermissions().contains(x))
                .collect(Collectors.toList());


        // 添加权限
        List<RolePermission> permissionList = unSelectPerm.stream().map(permId -> {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleDTO.getRole().getRoleId());
            rolePermission.setPermissionId(permId);
            return rolePermission;
        }).collect(Collectors.toList());
        boolean b1 = true;
        if (!permissionList.isEmpty())
            b1 = rolePermissionService.saveBatch(permissionList);

        boolean b2 = true;
        // 移除权限
        if (!removeSelPerm.isEmpty())
            b2 = rolePermissionService
                    .lambdaUpdate()
                    .eq(RolePermission::getRoleId, roleDTO.getRole().getRoleId())
                    .in(RolePermission::getPermissionId, removeSelPerm)
                    .remove();


        // 查找角色的已有admin
        List<Integer> ownAdmin = adminRoleService.lambdaQuery()
                .eq(AdminRole::getRoleId, roleDTO.getRole().getRoleId())
                .list().stream().map(AdminRole::getAdminId).collect(Collectors.toList());

        // 没有被选择的admin  需要添加新关系
        List<Integer> unSelectAdmin = roleDTO.getAdminInfos()
                .stream().filter(x -> !ownAdmin.contains(x)).collect(Collectors.toList());

        // 需要移除的admin
        List<Integer> removeSelAdmin = ownAdmin.stream()
                .filter(x -> !roleDTO.getAdminInfos().contains(x))
                .collect(Collectors.toList());


        // 添加admin
        List<AdminRole> adminList = unSelectAdmin.stream().map(adminId -> {
            AdminRole adminRole = new AdminRole();
            adminRole.setRoleId(roleDTO.getRole().getRoleId());
            adminRole.setAdminId(adminId);
            return adminRole;
        }).collect(Collectors.toList());
        boolean b3 = true;
        if (!adminList.isEmpty())
            b3 = adminRoleService.saveBatch(adminList);

        boolean b4 = true;
        // 移除admin
        if (!removeSelAdmin.isEmpty())
            b4 = adminRoleService
                    .lambdaUpdate()
                    .eq(AdminRole::getRoleId, roleDTO.getRole().getRoleId())
                    .in(AdminRole::getAdminId, removeSelAdmin)
                    .remove();

        return b1 && b2 && b1 && b2;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public boolean deleteByRoleId(Integer roleId) {
        // 删除角色，要对关系都解绑
        // 获取adminId
        List<Integer> adminIds = selectAdminByRoleId(roleId)
                .stream().map(AdminInfoVO::getAdminId).collect(Collectors.toList());
        // 获得权限id
        List<Integer> permissionIds = permissionService.getByRoleId(roleId)
                .stream().map(Permission::getPermissionId).collect(Collectors.toList());

        boolean r1 = true;

        if (!adminIds.isEmpty())

        r1 = adminRoleService.lambdaUpdate()
                .eq(AdminRole::getRoleId, roleId)
                .in(AdminRole::getAdminId, adminIds)
                .remove();
        boolean r2 = true;
        if (!permissionIds.isEmpty())
        r2 = rolePermissionService.lambdaUpdate()
                .eq(RolePermission::getRoleId, roleId)
                .in(RolePermission::getPermissionId, permissionIds)
                .remove();

        boolean b = removeById(roleId);

        return r1 && r2 && b;
    }
}




